
/*
@driver_st7735.c
@author: LH 
Creation Date��2023/05/11
*/
#include <string.h>
#include <stdio.h>
#include <stdbool.h>

#include "driver_spi.h"
#include "driver_gpio.h"
#include "driver_dma.h"
#include "driver_st7735.h"
#include "driver_pmu.h"
#include "sys_utils.h"
 
#define DEVELOP_FR8008GP_BOARD 1
 
#define LCD_RELEASE_CS()            gpio_write_pin(GPIO_D, GPIO_PIN_7, GPIO_PIN_SET)
#define LCD_SET_CS()                gpio_write_pin(GPIO_D, GPIO_PIN_7, GPIO_PIN_CLEAR)

#define LCD_RELEASE_DC()            gpio_write_pin(GPIO_C, GPIO_PIN_3, GPIO_PIN_SET)
#define LCD_SET_DC()                gpio_write_pin(GPIO_C, GPIO_PIN_3, GPIO_PIN_CLEAR)

#define LCD_RELEASE_RESET()         gpio_write_pin(GPIO_D, GPIO_PIN_0, GPIO_PIN_SET)
#define LCD_SET_RESET()             gpio_write_pin(GPIO_D, GPIO_PIN_0, GPIO_PIN_CLEAR)

#define LCD_ENABLE_BACKLIGHT()      pmu_set_gpio_value(GPIO_PORT_A, (1<<GPIO_BIT_5), 1)//gpio_write_pin(GPIO_A, GPIO_PIN_5, GPIO_PIN_SET)
#define LCD_DISABLE_BACKLIGHT()     pmu_set_gpio_value(GPIO_PORT_A, (1<<GPIO_BIT_5), 0);  //gpio_write_pin(GPIO_A, GPIO_PIN_5, GPIO_PIN_CLEAR)

#define LCD_ENABLE_POWER()      pmu_set_gpio_value(GPIO_PORT_D, (1<<GPIO_BIT_1), 0)//gpio_write_pin(GPIO_A, GPIO_PIN_5, GPIO_PIN_SET)
#define LCD_DISABLE_POWER()     pmu_set_gpio_value(GPIO_PORT_D, (1<<GPIO_BIT_1), 1);  //gpio_write_pin(GPIO_A, GPIO_PIN_5, GPIO_PIN_CLEAR)


#define LCD_W 80
#define LCD_H 160

 
void st7735_display_wait_transfer_done(void);
static DMA_LLI_InitTypeDef Link_Channel[5];
static DMA_HandleTypeDef st7735_DMA_Channel;
static dma_LinkParameter_t LinkParameter;
static volatile bool dma_transfer_done = true;

static SPI_HandleTypeDef ST7735_SPI_Handle;

static void (*dma_trans_done_callback)(void) = NULL;
 

 

static void st7735_init_io(void)
{
    GPIO_InitTypeDef GPIO_Handle;

    // backlight
//    GPIO_Handle.Pin       = GPIO_PIN_1;
//    GPIO_Handle.Mode      = GPIO_MODE_OUTPUT_PP;
//    gpio_init(GPIO_E, &GPIO_Handle);
 	 __SYSTEM_GPIO_CLK_ENABLE();
  
    // reset  DC   CS 
    GPIO_Handle.Pin       = GPIO_PIN_0;
    GPIO_Handle.Mode      = GPIO_MODE_OUTPUT_PP;
	GPIO_Handle.Alternate = GPIO_FUNCTION_0;
    gpio_init(GPIO_D, &GPIO_Handle);

	GPIO_Handle.Pin       = GPIO_PIN_3;
    GPIO_Handle.Mode      = GPIO_MODE_OUTPUT_PP;
	GPIO_Handle.Alternate = GPIO_FUNCTION_0;
    gpio_init(GPIO_C, &GPIO_Handle);
	
	GPIO_Handle.Pin       = GPIO_PIN_7;
    GPIO_Handle.Mode      = GPIO_MODE_OUTPUT_PP;
	GPIO_Handle.Alternate = GPIO_FUNCTION_0;
    gpio_init(GPIO_D, &GPIO_Handle);
	
//	GPIO_Handle.Pin       = GPIO_PIN_5;
//    GPIO_Handle.Mode      = GPIO_MODE_OUTPUT_PP;
//	GPIO_Handle.Alternate = GPIO_FUNCTION_0;
//    gpio_init(GPIO_A, &GPIO_Handle);
	
//    GPIO_Handle.Pin       = GPIO_PIN_4;//te 
//	GPIO_Handle.Pull      = GPIO_PULLUP; 
//    GPIO_Handle.Mode      = GPIO_MODE_INPUT;
//    gpio_init(GPIO_A, &GPIO_Handle);

    GPIO_Handle.Pin       = GPIO_PIN_6;//sclk
    GPIO_Handle.Mode      = GPIO_MODE_AF_PP;
    GPIO_Handle.Pull      = GPIO_PULLUP; 
    GPIO_Handle.Alternate = GPIO_FUNCTION_2;
    gpio_init(GPIO_D, &GPIO_Handle);
 
	GPIO_Handle.Pin       = GPIO_PIN_2;//sda io0
    GPIO_Handle.Mode      = GPIO_MODE_AF_PP;
    GPIO_Handle.Pull      = GPIO_PULLUP; 
    GPIO_Handle.Alternate = GPIO_FUNCTION_2;
    gpio_init(GPIO_C, &GPIO_Handle);
 
    LCD_RELEASE_CS();
    
	pmu_set_pin_to_PMU(GPIO_PORT_A,(1<<GPIO_BIT_5));
	//pmu_set_pin_pull(GPIO_PORT_A,(1<<GPIO_BIT_5),GPIO_PULL_UP);
    pmu_set_pin_dir(GPIO_PORT_A, (1<<GPIO_BIT_5), GPIO_DIR_OUT);
	//pmu_set_gpio_value(GPIO_PORT_A, (1<<GPIO_BIT_5), 1);  
	
	pmu_set_pin_to_PMU(GPIO_PORT_D,(1<<GPIO_BIT_1));
	//pmu_set_pin_pull(GPIO_PORT_A,(1<<GPIO_BIT_5),GPIO_PULL_UP);
    pmu_set_pin_dir(GPIO_PORT_D, (1<<GPIO_BIT_1), GPIO_DIR_OUT);
 	LCD_DISABLE_BACKLIGHT();
	
	LCD_ENABLE_POWER();
	co_delay_100us(10);
  //init_lcd_pwm();	
	
}

static void st7735_init_spi(void)
{
    __SYSTEM_SPI1_MASTER_CLK_SELECT_96M();
    __SYSTEM_SPI1_MASTER_CLK_ENABLE();
    
    ST7735_SPI_Handle.SPIx                       = SPIM1;
    ST7735_SPI_Handle.Init.Work_Mode             = SPI_WORK_MODE_0;
    ST7735_SPI_Handle.Init.Frame_Size            = SPI_FRAME_SIZE_8BIT;
    ST7735_SPI_Handle.Init.BaudRate_Prescaler    = 2;
    ST7735_SPI_Handle.Init.TxFIFOEmpty_Threshold = 15;
    ST7735_SPI_Handle.Init.RxFIFOFull_Threshold  = 0;

    spi_master_init(&ST7735_SPI_Handle);
}

static void st7735_init_dma(void)
{    
    __SYSTEM_DMA_CLK_ENABLE();
    __DMA_REQ_ID_SPI1_MASTER_TX(1);
    
    st7735_DMA_Channel.Channel = DMA_Channel0;
    st7735_DMA_Channel.Init.Data_Flow        = DMA_M2P_DMAC;
    st7735_DMA_Channel.Init.Request_ID       = 1;
    st7735_DMA_Channel.Init.Source_Inc       = DMA_ADDR_INC_INC;
    st7735_DMA_Channel.Init.Desination_Inc   = DMA_ADDR_INC_NO_CHANGE;
    st7735_DMA_Channel.Init.Source_Width     = DMA_TRANSFER_WIDTH_32;
    st7735_DMA_Channel.Init.Desination_Width = DMA_TRANSFER_WIDTH_16;
    dma_init(&st7735_DMA_Channel);

    NVIC_EnableIRQ(DMA_IRQn);
}

static void st7735_write_cmd(uint8_t cmd)
{
    uint8_t spi_data[4];

    spi_data[0]=cmd;
		LCD_SET_DC();
    LCD_SET_CS();
    spi_master_transmit_X1(&ST7735_SPI_Handle, (uint16_t *)spi_data, 1);
    LCD_RELEASE_CS();

}

static void st7735_write_data(uint8_t data)
{
    uint8_t spi_data[4];

    spi_data[0]=data;
	  LCD_RELEASE_DC();
    LCD_SET_CS();
    spi_master_transmit_X1(&ST7735_SPI_Handle, (uint16_t *)spi_data, 1);
    LCD_RELEASE_CS();
}


static void st7735_write_16bit_data(uint16_t data)
{
    uint8_t spi_data[4];
    spi_data[0]=data>>8;
	spi_data[1]=data;
	LCD_RELEASE_DC();
    LCD_SET_CS();
	__SPI_DATA_FRAME_SIZE(ST7735_SPI_Handle.SPIx,SPI_FRAME_SIZE_16BIT);
    spi_master_transmit_X1(&ST7735_SPI_Handle, (uint16_t *)spi_data, 2);
    LCD_RELEASE_CS();
	__SPI_DATA_FRAME_SIZE(ST7735_SPI_Handle.SPIx,SPI_FRAME_SIZE_8BIT);
}


 
 



/******************************************************************************
      ����˵����LCD��������
      ������ݣ���
      ����ֵ��  ��
******************************************************************************/
void st7735_Clear(uint16_t Color)
{
	uint16_t i,j;  
		
	st7735_set_window(0,LCD_W-1,0,LCD_H-1);
	for(i=0;i<LCD_W;i++)
	{
		for(j=0;j<LCD_H;j++)
	   	{
        	st7735_write_16bit_data(Color);	 			 
	    }
 
	 }
}
 
static uint16_t swap_endian(uint16_t value) {
    return ((value & 0xFF) << 8) | ((value & 0xFF00) >> 8);
}
 
void st7735_hard_init(void)
{
	pmu_set_pin_to_CPU(GPIO_PORT_D, (1<<GPIO_BIT_7));	
	pmu_set_pin_to_CPU(GPIO_PORT_D, (1<<GPIO_BIT_0));
	pmu_set_pin_to_CPU(GPIO_PORT_D, (1<<GPIO_BIT_6));
	
	pmu_set_pin_to_CPU(GPIO_PORT_C, (1<<GPIO_BIT_2));
	pmu_set_pin_to_CPU(GPIO_PORT_C, (1<<GPIO_BIT_3));
//    st7735_init_io();
//    st7735_init_spi();
//    st7735_init_dma();
	
}

void st7735_hard_deinit(void)
{
	#if 1
    pmu_set_pin_to_PMU(GPIO_PORT_D,(1<<GPIO_BIT_0));
	pmu_set_pin_pull(GPIO_PORT_D,(1<<GPIO_BIT_0),GPIO_PULL_NONE);
    pmu_set_pin_dir(GPIO_PORT_D, (1<<GPIO_BIT_0), GPIO_DIR_IN);
 
	pmu_set_pin_to_PMU(GPIO_PORT_D,(1<<GPIO_BIT_7));
	pmu_set_pin_pull(GPIO_PORT_D,(1<<GPIO_BIT_7),GPIO_PULL_NONE);
    pmu_set_pin_dir(GPIO_PORT_D, (1<<GPIO_BIT_7), GPIO_DIR_IN);
	
	pmu_set_pin_to_PMU(GPIO_PORT_C,(1<<GPIO_BIT_3));
	pmu_set_pin_pull(GPIO_PORT_C,(1<<GPIO_BIT_3),GPIO_PULL_NONE);
    pmu_set_pin_dir(GPIO_PORT_C, (1<<GPIO_BIT_3), GPIO_DIR_IN);
	
	pmu_set_pin_to_PMU(GPIO_PORT_C,(1<<GPIO_BIT_2));
	pmu_set_pin_pull(GPIO_PORT_C,(1<<GPIO_BIT_2),GPIO_PULL_NONE);
    pmu_set_pin_dir(GPIO_PORT_C, (1<<GPIO_BIT_2), GPIO_DIR_IN);
	
	pmu_set_pin_to_PMU(GPIO_PORT_D,(1<<GPIO_BIT_6));
	pmu_set_pin_pull(GPIO_PORT_D,(1<<GPIO_BIT_6),GPIO_PULL_NONE);
    pmu_set_pin_dir(GPIO_PORT_D, (1<<GPIO_BIT_6), GPIO_DIR_IN);
	
	 pmu_set_pin_to_PMU(GPIO_PORT_A,(1<<GPIO_BIT_4));
	pmu_set_pin_pull(GPIO_PORT_A,(1<<GPIO_BIT_4),GPIO_PULL_NONE);
    pmu_set_pin_dir(GPIO_PORT_A, (1<<GPIO_BIT_4), GPIO_DIR_IN);
	
	pmu_set_pin_to_PMU(GPIO_PORT_D,(1<<GPIO_BIT_1));
	pmu_set_pin_pull(GPIO_PORT_D,(1<<GPIO_BIT_1),GPIO_PULL_NONE);
    pmu_set_pin_dir(GPIO_PORT_D, (1<<GPIO_BIT_1), GPIO_DIR_IN);
	
	pmu_set_pin_to_PMU(GPIO_PORT_A,(1<<GPIO_BIT_5));
	pmu_set_pin_pull(GPIO_PORT_A,(1<<GPIO_BIT_5),GPIO_PULL_NONE);
    pmu_set_pin_dir(GPIO_PORT_A, (1<<GPIO_BIT_5), GPIO_DIR_IN);
	#else
	pmu_set_pin_to_PMU(GPIO_PORT_D,(1<<GPIO_BIT_0));
    pmu_set_pin_dir(GPIO_PORT_D, (1<<GPIO_BIT_0), GPIO_DIR_OUT);
	pmu_set_gpio_value(GPIO_PORT_D,(1<<GPIO_BIT_0),0);
	
	pmu_set_pin_to_PMU(GPIO_PORT_D,(1<<GPIO_BIT_7));
	pmu_set_pin_pull(GPIO_PORT_D,(1<<GPIO_BIT_7),GPIO_PULL_NONE);
    pmu_set_pin_dir(GPIO_PORT_D, (1<<GPIO_BIT_7), GPIO_DIR_OUT);
	pmu_set_gpio_value(GPIO_PORT_D,(1<<GPIO_BIT_7),0);
	
	pmu_set_pin_to_PMU(GPIO_PORT_C,(1<<GPIO_BIT_3));
	pmu_set_pin_pull(GPIO_PORT_C,(1<<GPIO_BIT_3),GPIO_PULL_NONE);
    pmu_set_pin_dir(GPIO_PORT_C, (1<<GPIO_BIT_3), GPIO_DIR_OUT);
	pmu_set_gpio_value(GPIO_PORT_C,(1<<GPIO_BIT_3),0);
	
	pmu_set_pin_to_PMU(GPIO_PORT_C,(1<<GPIO_BIT_2));
	pmu_set_pin_pull(GPIO_PORT_C,(1<<GPIO_BIT_2),GPIO_PULL_NONE);
    pmu_set_pin_dir(GPIO_PORT_C, (1<<GPIO_BIT_2), GPIO_DIR_OUT);
	pmu_set_gpio_value(GPIO_PORT_C,(1<<GPIO_BIT_2),0);
	
	pmu_set_pin_to_PMU(GPIO_PORT_D,(1<<GPIO_BIT_6));
	pmu_set_pin_pull(GPIO_PORT_D,(1<<GPIO_BIT_6),GPIO_PULL_NONE);
    pmu_set_pin_dir(GPIO_PORT_D, (1<<GPIO_BIT_6), GPIO_DIR_OUT);
	pmu_set_gpio_value(GPIO_PORT_D,(1<<GPIO_BIT_6),0);
	#endif
//    __SYSTEM_GPIO_CLK_DISABLE(); 
//    __SYSTEM_SPI1_MASTER_CLK_DISABLE();
//	__SYSTEM_DMA_CLK_DISABLE();
//	
//	pmu_set_pin_to_PMU(GPIO_PORT_D,(1<<GPIO_BIT_0));
//	pmu_set_pin_pull(GPIO_PORT_D,(1<<GPIO_BIT_0),GPIO_PULL_UP);
//    pmu_set_pin_dir(GPIO_PORT_D, (1<<GPIO_BIT_0), GPIO_DIR_OUT);
//	pmu_set_gpio_value(GPIO_PORT_D, (1<<GPIO_BIT_0), 1);  
//    
//	pmu_set_pin_to_PMU(GPIO_PORT_D,(1<<GPIO_BIT_7));
//	pmu_set_pin_pull(GPIO_PORT_D,(1<<GPIO_BIT_7),GPIO_PULL_UP);
//    pmu_set_pin_dir(GPIO_PORT_D, (1<<GPIO_BIT_7), GPIO_DIR_OUT);
//	pmu_set_gpio_value(GPIO_PORT_D, (1<<GPIO_BIT_7), 1);
	
//	pmu_set_pin_to_PMU(GPIO_PORT_D,(1<<GPIO_BIT_0));
//	pmu_set_pin_pull(GPIO_PORT_D,(1<<GPIO_BIT_0),GPIO_PULL_UP);
//    pmu_set_pin_dir(GPIO_PORT_D, (1<<GPIO_BIT_0), GPIO_DIR_OUT);
//	pmu_set_gpio_value(GPIO_PORT_D, (1<<GPIO_BIT_0), 1); 
}
void st7735_init(void)
{
	st7735_hard_init();
    st7735_init_io();
    st7735_init_spi();
    st7735_init_dma();
	
	LCD_RELEASE_RESET();
	co_delay_100us(10);
	LCD_SET_RESET();
//	co_delay_100us(500);
	co_delay_100us(30);
	LCD_RELEASE_RESET();
	co_delay_100us(1200);     
	st7735_write_cmd(0x11);     //Sleep out

	#if 1 //新屏幕
	//co_delay_100us(1200);
	st7735_write_cmd(0xB1);     
	st7735_write_data(0x05);   
	st7735_write_data(0x3C);   
	st7735_write_data(0x3C);   

	st7735_write_cmd(0xB2);     
	st7735_write_data(0x05);   
	st7735_write_data(0x3C);   
	st7735_write_data(0x3C);   

	st7735_write_cmd(0xB3);     
	st7735_write_data(0x05);   
	st7735_write_data(0x3C);   
	st7735_write_data(0x3C);   
	st7735_write_data(0x05);   
	st7735_write_data(0x3C);   
	st7735_write_data(0x3C);   

	st7735_write_cmd(0xB4);     //Dot inversion
	st7735_write_data(0x03); 
	st7735_write_data(0x02);  

	st7735_write_cmd(0xC0);     
	st7735_write_data(0xE0);   
	st7735_write_data(0x00);   
	st7735_write_data(0x84);   

	st7735_write_cmd(0xC1);     
	st7735_write_data(0xC4);   

	st7735_write_cmd(0xC2);     
	st7735_write_data(0x0D);   
	st7735_write_data(0x00);   
	
	st7735_write_cmd(0xC3);     
	st7735_write_data(0x8D);   
	st7735_write_data(0x2A);   

	st7735_write_cmd(0xC4);     
	st7735_write_data(0x8D);   
	st7735_write_data(0xEE);   

	st7735_write_cmd(0xC5);
	st7735_write_data(0x04);

	st7735_write_cmd(0xE0);
	st7735_write_data(0x09);
	st7735_write_data(0x18);
	st7735_write_data(0x1A);
	st7735_write_data(0x21);
	st7735_write_data(0x3F);
	st7735_write_data(0x3B);
	st7735_write_data(0x31);
	st7735_write_data(0x32);
	st7735_write_data(0x2F);
	st7735_write_data(0x2A);
	st7735_write_data(0x30);
	st7735_write_data(0x37);
	st7735_write_data(0x00);
	st7735_write_data(0x05);
	st7735_write_data(0x00);
	st7735_write_data(0x10);

	st7735_write_cmd(0xE1);
	st7735_write_data(0x07);
	st7735_write_data(0x14);
	st7735_write_data(0x15);
	st7735_write_data(0x1A);
	st7735_write_data(0x3F);
	st7735_write_data(0x33);
	st7735_write_data(0x2C);
	st7735_write_data(0x2E);
	st7735_write_data(0x2B);
	st7735_write_data(0x28);
	st7735_write_data(0x2F);
	st7735_write_data(0x3E);
	st7735_write_data(0x00);
	st7735_write_data(0x04);
	st7735_write_data(0x02);
	st7735_write_data(0x10);
	
	st7735_write_cmd(0x35);     
	st7735_write_data(0x00);   
	st7735_write_cmd(0x3A);     //65k mode
	st7735_write_data(0x05);   
	st7735_write_cmd(0x36);     
	st7735_write_data(0xC8);

	st7735_write_cmd(0x21);    

	st7735_write_cmd(0x29);     //Display on  
	
	#else //旧屏幕
	st7735_write_cmd( 0xB1);     
	st7735_write_data( 0x05);   
	st7735_write_data( 0x3A);   
	st7735_write_data( 0x3A);   

	st7735_write_cmd( 0xB2);     
	st7735_write_data( 0x05);   
	st7735_write_data( 0x3A);   
	st7735_write_data( 0x3A);   

	st7735_write_cmd( 0xB3);     
	st7735_write_data( 0x05);   
	st7735_write_data( 0x3A);   
	st7735_write_data( 0x3A);   
	st7735_write_data( 0x05);   
	st7735_write_data( 0x3A);   
	st7735_write_data( 0x3A);   //------------------------------------End ST7735S Frame Rate-----------------------------------------//

	st7735_write_cmd( 0xB4);     //Dot inversion
	st7735_write_data( 0x03);   

	st7735_write_cmd( 0xC0);     //------------------------------------ST7735S Power Sequence-----------------------------------------//
	st7735_write_data( 0x0E);   
	st7735_write_data( 0x0E);   
	st7735_write_data( 0x04);   

	st7735_write_cmd( 0xC1);     
	st7735_write_data( 0xC0);   

	st7735_write_cmd( 0xC2);     
	st7735_write_data( 0x0D);   
	st7735_write_data( 0x00);   

	st7735_write_cmd( 0xC3);     
	st7735_write_data( 0x8D);   
	st7735_write_data( 0x2A);   

	st7735_write_cmd( 0xC4);     
	st7735_write_data( 0x8D);   
	st7735_write_data( 0xEE);   //---------------------------------End ST7735S Power Sequence-------------------------------------//

	st7735_write_cmd( 0xC5);     //VCOM
	st7735_write_data( 0x04);   

   

	st7735_write_cmd( 0xE0);
	st7735_write_data( 0x10);
	st7735_write_data( 0x0E);
	st7735_write_data( 0x02);
	st7735_write_data( 0x03);
	st7735_write_data( 0x0E);
	st7735_write_data( 0x07);
	st7735_write_data( 0x02);
	st7735_write_data( 0x07);
	st7735_write_data( 0x0A);
	st7735_write_data( 0x12);
	st7735_write_data( 0x27);
	st7735_write_data( 0x37);
	st7735_write_data( 0x00);
	st7735_write_data( 0x0D);
	st7735_write_data( 0x0E);
	st7735_write_data( 0x10);

	st7735_write_cmd( 0xE1);
	st7735_write_data( 0x10);
	st7735_write_data( 0x0E);
	st7735_write_data( 0x03);
	st7735_write_data( 0x03);
	st7735_write_data( 0x0F);
	st7735_write_data( 0x06);
	st7735_write_data( 0x02);
	st7735_write_data( 0x08);
	st7735_write_data( 0x0A);
	st7735_write_data( 0x13);
	st7735_write_data( 0x26);
	st7735_write_data( 0x36);
	st7735_write_data( 0x00);
	st7735_write_data( 0x0D);
	st7735_write_data( 0x0E);
	st7735_write_data( 0x10);  

	st7735_write_cmd( 0x36);     //MX, MY, RGB mode
	st7735_write_data( 0x08);
	
	st7735_write_cmd(0x3A); //65k mode
	st7735_write_data(0x05);
	 st7735_write_cmd(0x21); 
	st7735_write_cmd( 0x29);     //Display on

#endif
	//co_delay_100us(1200);
	LCD_SET_CS();
	
//    st7735_Clear(0xf800);
// 	co_delay_100us(12000);
//    st7735_Clear(0x001f);
// 	co_delay_100us(1200);
//	co_delay_100us(1200);
//	st7735_Clear(0xf800);
//	co_delay_100us(1200);
//	st7735_Clear(0x01e0);
//	extern  const  uint8_t color_blocks_map[] ;
//	static uint16_t PSRAM_LCD_FRAME_BUFFER_ORIGIN[128*40];
//	for(uint32_t i = 0; i < 128*40; i++)PSRAM_LCD_FRAME_BUFFER_ORIGIN[i]   =swap_endian(0xf800);
//	//while(1)
//	{
//		for(uint32_t i = 0; i < 128*40; i++)PSRAM_LCD_FRAME_BUFFER_ORIGIN[i]   =swap_endian(0xf800);
//		st7735_set_window(0, 128-1,0, 40-1);	 
//		st7735_display((128*40),PSRAM_LCD_FRAME_BUFFER_ORIGIN,NULL);
//		st7735_display_wait_transfer_done();
//		
//		for(uint32_t i = 0; i < 128*40; i++)PSRAM_LCD_FRAME_BUFFER_ORIGIN[i]   =swap_endian(0x001f);
//		st7735_set_window(0, 128-1,40, 40-1);	 
//		st7735_display((128*40),PSRAM_LCD_FRAME_BUFFER_ORIGIN,NULL);
//		st7735_display_wait_transfer_done();
//		
//		for(uint32_t i = 0; i < 128*40; i++)PSRAM_LCD_FRAME_BUFFER_ORIGIN[i]   =swap_endian(0x07e0);
//		st7735_set_window(0, 128-1,80, 40-1);	 
//		st7735_display((128*40),PSRAM_LCD_FRAME_BUFFER_ORIGIN,NULL);
//		st7735_display_wait_transfer_done();
//		
//		for(uint32_t i = 0; i < 128*40; i++)PSRAM_LCD_FRAME_BUFFER_ORIGIN[i]   =swap_endian(0xffff);
//		st7735_set_window(0, 128-1,120, 40-1);	 
//		st7735_display((128*40),PSRAM_LCD_FRAME_BUFFER_ORIGIN,NULL);
//		st7735_display_wait_transfer_done();
//	}
	//co_delay_100us(10000);
}

void st7735_set_window(uint16_t x_s, uint16_t x_e, uint16_t y_s, uint16_t y_e)
{
	   
	#if 0
	st7735_write_cmd(0x2a);//�е�ַ����
	
	st7735_write_data(x_s);
	st7735_write_data(x_e);
	st7735_write_cmd(0x2b);//�е�ַ����
	st7735_write_data(y_s);
	st7735_write_data(y_e);
 
    st7735_write_cmd(0x2c);//������д
	#else
	st7735_write_cmd(0x2a);//�е�ַ����
	
	st7735_write_16bit_data(x_s+26);
	st7735_write_16bit_data(x_e+26);
	st7735_write_cmd(0x2b);//�е�ַ����
	st7735_write_16bit_data(y_s+1);
	st7735_write_16bit_data(y_e+1);
 
    st7735_write_cmd(0x2c);//������д
	#endif
}

void st7735_display_wait_transfer_done(void)
{
    while(dma_transfer_done == false);
}

void st7735_display(uint32_t pixel_count, uint16_t *data, void (*callback)(void))
{
	#if 1
	  uint32_t i;
    uint32_t total_count = pixel_count / 2;   // accoding source width
    uint8_t link_count = total_count / 4000;
    
    if(dma_transfer_done == false)
    {
        return;
    }
    else
    {
        dma_transfer_done = false;
    }
    
    dma_trans_done_callback = callback;
    
    if(total_count % 4000)
    {
        link_count++;
    }
    
    for (i = 0; i < link_count; i++)
    {
        uint8_t all_set = (total_count <= 4000);
        
        LinkParameter.SrcAddr          = (uint32_t)&data[i * 8000];
        LinkParameter.DstAddr          = (uint32_t)&ST7735_SPI_Handle.SPIx->DR;
        if(all_set)
        {
            LinkParameter.NextLink     = 0;
        }
        else
        {
            LinkParameter.NextLink     = (uint32_t)&Link_Channel[i + 1];
        }
        LinkParameter.Data_Flow        = DMA_M2P_DMAC;
        LinkParameter.Request_ID       = st7735_DMA_Channel.Init.Request_ID;
        LinkParameter.Source_Inc       = DMA_ADDR_INC_INC;
        LinkParameter.Desination_Inc   = DMA_ADDR_INC_NO_CHANGE;
        LinkParameter.Source_Width     = DMA_TRANSFER_WIDTH_32;
        LinkParameter.Desination_Width = DMA_TRANSFER_WIDTH_8;
        LinkParameter.Burst_Len        = DMA_BURST_LEN_4;
        LinkParameter.Size             = all_set ? (total_count) : 4000;
        LinkParameter.gather_enable    = 0;
        LinkParameter.scatter_enable   = 0;
        total_count -= 4000;

        dma_linked_list_init(&Link_Channel[i], &LinkParameter);
    }
//	
	//__SPI_DATA_FRAME_SIZE(ST7735_SPI_Handle.SPIx,SPI_FRAME_SIZE_8BIT);
	LCD_RELEASE_DC();
    LCD_SET_CS();
    spi_master_transmit_X1_DMA(&ST7735_SPI_Handle);
    dma_linked_list_start_IT(Link_Channel, &LinkParameter, st7735_DMA_Channel.Channel);
	#endif
	 
		//send_data_disp((uint8_t*)data,240*240*2);
}
 
void st7735_sleep_in(void)
{
	
	LCD_DISABLE_BACKLIGHT();
	//LCD_DISABLE_POWER();
//	st7735_write_cmd(0x28);//Display off
//	co_delay_100us(1000);
//	st7735_write_cmd(0x10);	//Normal-Mode -> Sleep In-Mode
//	co_delay_100us(1500);
	st7735_hard_deinit();
}

void st7735_sleep_out(void)
{
	st7735_write_cmd(0x11);	//Sleep In-Mode -> Normal-Mode
	co_delay_100us(100);
	st7735_write_cmd(0x29);//Display on
	//co_delay_100us(100);
	LCD_ENABLE_BACKLIGHT();
}

void st7735_backlight_open(void)
{
	LCD_ENABLE_BACKLIGHT();
}

void st7735_backlight_close(void)
{
	LCD_DISABLE_BACKLIGHT();
}
__attribute__((section("ram_code"))) void st7735_dma_isr(void)
{
    void (*callback)();
    while(__SPI_IS_BUSY(ST7735_SPI_Handle.SPIx));
	 //	printf("dma_isr\r\n");
    // CS Release
    LCD_RELEASE_CS();
	
    /* Clear Transfer complete status */
    dma_clear_tfr_Status(st7735_DMA_Channel.Channel);
    /* channel Transfer complete interrupt disable */
    dma_tfr_interrupt_disable(st7735_DMA_Channel.Channel);

    __SPI_DISABLE(ST7735_SPI_Handle.SPIx);
 //   __SPI_DATA_FRAME_SIZE(ST7735_SPI_Handle.SPIx, SPI_FRAME_SIZE_8BIT);
    
    dma_transfer_done = true;
    callback = dma_trans_done_callback;
    dma_trans_done_callback = NULL;
    if(callback) {
        callback();
    }
}
//__attribute__((section("ram_code"))) void dma_isr(void)
//{
//		st7735_dma_isr();
//}
